package org.example.pro2_apobase.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//实现InvocationHandler接口，实现invoke方法
public class MyAdviceInvocationHandler implements InvocationHandler {
    //第二步====================
    //调用代理类也会取目标类的方法，所以需要目标类的对象
    //目标对象
    private Object target;
    public MyAdviceInvocationHandler(Object target){
        this.target=target;
    }

    //第三步======================
    //通过目标类 来  获取代理对象
    //通过目标类的接口实现代理对象
    //Proxy.newProxyInstance  是一个静态方法，用于创建代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(
                //目标类的类加载器
                MyAdviceInvocationHandler.class.getClassLoader(),
                //target.getClass().getClassLoader(),  //也可以这样写
                //目标类的接口
                target.getClass().getInterfaces(),   //可知，若目标类有多个接口，则会创建多个代理对象
                //当前对象
                this
        );
    }

    //第一步================================
    //invoke 是激活方法，也是回调函数  当客户端调用代理对象的方法时，会自动调用invoke方法
    //proxy 代理对象    method 当前调用的方法对象    args 当前调用方法的方法参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //第5步
        //实现增强方法的逻辑
        //前置增强  目标类方法还没执行，先进行判定权限
        if(method.getName().startsWith("save")||method.getName().startsWith("update")){  //@Pointcut("execution(* org.example.pro1.service.*.save*(..))")  //切入点表达式
            checkRight();
        }
        //目标类的方法执行   目标类的方法执行
        Object returnValue=method.invoke(target,args);
        //后置增强
        if(method.getName().startsWith("find")||method.getName().startsWith("show")){  //@Pointcut("execution(* org.example.pro1.service.*.find*(..))")  //切入点表达式
            log();
        }


        return returnValue;
    }


    //第四步==============================
    //增强方法  对目标类的方法进行增强
    //第5步相当于 在方法上面加入注解
    //@Before
    public void checkRight(){
        System.out.println("==================");
        System.out.println("权限验证通过");
        System.out.println("===============");
    }

    //@After
    public void log(){
        System.out.println("==================");
        System.out.println("输出日志");
        System.out.println("===============");
    }
}
